package com.westar.core.services;

import com.westar.base.businessUtil.ChangePwdUtil;
import com.westar.base.businessUtil.UserPageUtil;
import com.westar.base.cons.Constant;
import com.westar.base.exceptions.SelfHttpException;
import com.westar.base.model.UserDepAreaRelate;
import com.westar.base.model.UserInfo;
import com.westar.base.pojo.PageBean;
import com.westar.base.pojo.WestarResult;
import com.westar.base.util.CodeUtil;
import com.westar.base.util.MyLevenshtein;
import com.westar.base.util.TokenUtil;
import com.westar.base.util.WestarHttpUtil;
import com.westar.core.conf.SysConst;
import com.westar.core.dao.UserInfoDao;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;

/**
 * 用户操作service
 */
@Service
public class UserInfoService {

    @Autowired
    private UserInfoDao userInfoDao;

    @Autowired
    private SystemLogService systemLogService;

    @Autowired
    private AccountLimitService accountLimitService;

    private static final Logger logger = LoggerFactory.getLogger(UserInfoService.class);

    /**
     * 更新用户信息
     * @param account 账号
     * @param password 密码
     */
    public void updateUserInfo(String account, String password) {
        String md5 = CodeUtil.md5Encode(password);
        userInfoDao.updateUserInfo(account,password,md5);
    }
    /**
     * 更新Md5库信息
     * @param password 密码
     */
    public void updatePasswdMd5(String password) {
        String md5 = CodeUtil.md5Encode(password);
        userInfoDao.updatePasswdMd5(password,md5);
    }

    /**
     * 根据用户账号获取用户信息
     * @param account 账号
     * @return 当前操作人员的登录信息
     */
    public UserInfo getUserInfoByAccount(String account){
        //取得用户的登录信息
        UserInfo userInfo = userInfoDao.getUserInfoByAccount(account);
        return userInfo;
    }

    /**
     * 初始化常用的账号的密码
     * @param actCookie
     * @throws IOException
     */
    public void initUsedUser(String actCookie) throws IOException {
        List<UserInfo> userInfoList = userInfoDao.listAllOperator(null);
        if(null != userInfoList && userInfoList.isEmpty()){

            List<String> updatedPasswdList = new ArrayList<>();

            for (UserInfo userInfo : userInfoList) {
                String loginIdName = userInfo.getAccount();

                //查询密码的次数，判定管是否需要限定时间再次登录
                int errorCount = accountLimitService.countAccountLimit(loginIdName);
                if(errorCount > 5 ){
                    systemLogService.addSystemLog(loginIdName,"-","-1","密码错误超过五次！");
                    continue;
                }

                String prePassmd5 = userInfo.getMd5();
                PageBean<UserDepAreaRelate> pageBean = UserPageUtil.listPagedUserFromUp(actCookie,1,10,loginIdName);
                //取得记录信息集合
                List<UserDepAreaRelate> recordList = pageBean.getRecordList();
                //添加数据
                if(null != recordList && !recordList.isEmpty()){
                    UserDepAreaRelate userDepAreaRelate = recordList.get(0);
                    String md5Passwd = userDepAreaRelate.getMd5Passwd();
                    if(!md5Passwd.equals(prePassmd5)){
                        userInfoDao.updateUserDepAreaRelate(loginIdName,userDepAreaRelate.getMd5Passwd());
                        updatedPasswdList.add(loginIdName);
                    }
                }

                //登录成功，删除所有的密码错误记录
                accountLimitService.deleteAccountLimit(loginIdName);
            }

            //查询userInfo中密码为空的或是MD5与userDepAreaRelate中密码不同的
            List<UserInfo> listUserInfo = userInfoDao.listToMd5User();
            if(null != listUserInfo){
                for (UserInfo userInfo: listUserInfo) {
                    String loginIdName = userInfo.getAccount();
                    String password = userInfo.getPasswd();
                    if(StringUtils.isEmpty(password)){
                        password = "-";
                        if(!updatedPasswdList.contains(loginIdName)){
                            systemLogService.addSystemLog("-","-","-1",loginIdName+"的密码有变动！");
                            //TODO 密码有变动的通知
                        }
                    }
                    userInfoDao.updateUserInfo(userInfo.getAccount(),password,userInfo.getMd5());
                }
            }
        }

    }

    /**
     * 同步一体化平台账号信息
     * @param actCookie
     * @throws IOException
     */
    public void initUser(String actCookie) throws IOException {

        //删除所有用户关系
        userInfoDao.delTable("userDepAreaRelate" );

        Integer rows = 100;

        //分页查询一体化平台的用户
        PageBean<UserDepAreaRelate> pageBean = UserPageUtil.listPagedUserFromUp(actCookie,1,rows,null);
        //取得记录信息集合
        List<UserDepAreaRelate> recordList = pageBean.getRecordList();
        //有记录信息
        if(null != recordList && !recordList.isEmpty()){
            //第一次添加数据
            for (UserDepAreaRelate userDepAreaRelate:  recordList) {
                userInfoDao.add(userDepAreaRelate);
            }
            //总条数
            Integer total = pageBean.getTotalCount();
            //总页数
            Integer totalPageNum = total/rows + 1;
            //查询剩下的页码信息
            for(int i = 2; i <= totalPageNum; i++){
                //分页查询一体化平台的用户
                pageBean = UserPageUtil.listPagedUserFromUp(actCookie,i,rows,null);
                //取得记录信息集合
                recordList = pageBean.getRecordList();
                //添加数据
                if(null != recordList && !recordList.isEmpty()){
                    for (UserDepAreaRelate implementDetail:  recordList) {
                        userInfoDao.add(implementDetail);
                    }
                }
            }

            //更新md5 信息
            this.updateAllMd5();
        }

    }

    /**
     * 跟新人员后的md5更新
     */
    private void updateAllMd5() {
        //查询userInfo中密码为空的或是MD5与userDepAreaRelate中密码不同的
        List<UserInfo> listUserInfo = userInfoDao.listToMd5User();
        if(null != listUserInfo){
            for (UserInfo userInfo: listUserInfo) {
                String password = userInfo.getPasswd();
                if(StringUtils.isEmpty(password)){
                    password = "-";
                }
                userInfoDao.updateUserInfo(userInfo.getAccount(),password,userInfo.getMd5());
            }
        }
    }

    /**
     * 查询需要解析md5的用户
     */
    public  List<UserInfo>  listUserForPasswd(){
        List<UserInfo> userInfoList = userInfoDao.listUserForPasswd();
        return userInfoList;
    }
    /**
     * 初始化用户账号信息
     */
    public void initAdminAccount() {
        UserInfo userInfo = userInfoDao.getUserInfoByAccount(SysConst.ADMIN_ACCOUNT);
        if(null == userInfo){
            userInfo = new UserInfo();
            userInfo.setAccount(SysConst.ADMIN_ACCOUNT);
            userInfo.setPasswd( SysConst.ADMIN_PASSWD);
            userInfoDao.add(userInfo);
        }
    }

    /**
     * 查询办理的候选人列表
     * @param transactors
     */
    public List<UserInfo>  listAllOperator(String transactors,String account) {
        String[] users = transactors.split(";");

        if(null!=users && users.length>0 ){
            List<UserDepAreaRelate> userDepAreaRelateList=  userInfoDao.listAllUserDepAreaRelate(users);
            Map<String,List<UserDepAreaRelate>> nameToAccountMap = new HashMap<>();
            //初始化用户信息
            for (UserDepAreaRelate userDepAreaRelate:userDepAreaRelateList ) {
                //办理人姓名
                String executorName = userDepAreaRelate.getName();
                List<UserDepAreaRelate> executorAccounts = nameToAccountMap.getOrDefault(executorName,new ArrayList<>());
                executorAccounts.add(userDepAreaRelate);
                nameToAccountMap.put(executorName,executorAccounts);
            }

            Set<Map.Entry<String,List<UserDepAreaRelate>>> entries = nameToAccountMap.entrySet();
            Iterator<Map.Entry<String,List<UserDepAreaRelate>>> itor = entries.iterator();
            while (itor.hasNext()){
                Map.Entry<String,List<UserDepAreaRelate>> entry = itor.next();
                List<UserDepAreaRelate> executorAccounts = entry.getValue();
                if(null!=executorAccounts &&executorAccounts.size() == 1){
                    String accountTemp = executorAccounts.get(0).getAccount();
                    this.checkExecutor(accountTemp);
                }else if(null!=executorAccounts &&executorAccounts.size() >1){
                    List<UserDepAreaRelate> executorAccountsV2 = new ArrayList<>();
                    for (UserDepAreaRelate accountTemp: executorAccounts) {
                        String accountV2 = accountTemp.getAccount();
                        float score = MyLevenshtein.levenshtein(account,accountV2);
                        if(score > 0.7f){
                            executorAccountsV2.add(accountTemp);
                        }
                    }
                    if(null!=executorAccountsV2 &&executorAccountsV2.size() == 1){
                        String accountTemp = executorAccountsV2.get(0).getAccount();
                        this.checkExecutor(accountTemp);
                    }
                }

            }
        }




        List<UserInfo> allChooseUser = userInfoDao.listAllOperator(users);
        return allChooseUser;
    }
    /**
     * 初始化用户的md5
     */
    public void initUserPasswd() {
        //查询所有没有md5的用户
        List<UserInfo> userInfoList = userInfoDao.listAllUserWithoutMd5();
        if(null != userInfoList){
            for (UserInfo userInfo : userInfoList) {
                //修改用户的md5
                this.updateUserInfo(userInfo.getAccount(),userInfo.getPasswd());
                //更新md5库
                this.updatePasswdMd5(userInfo.getPasswd());
            }
        }
    }

    /**
     * 获取数据库的用户密码
     * @param account
     * @return
     */
    public String getPasswdByAccount(String account) {
        UserInfo userInfo = userInfoDao.getUserInfoByAccount(account);
        return userInfo.getPasswd();
    }
    /**
     * 获取数据库的用户密码
     * @param account
     * @return
     */
    public String getPasswdByAccountWithMd5(String account) {
        UserInfo userInfo = userInfoDao.getUserInfoByAccountWithMd5(account);
        if(null!=userInfo){
            return userInfo.getPasswd();
        }else{
            return null;
        }

    }

    /**
     * 更新用户的md5
     * @param account
     * @param password
     */
    public void updateUserDepAreaRelate(String account, String password) {
        String md5 = CodeUtil.md5Encode(password);
        userInfoDao.updateUserDepAreaRelate(account,md5);
    }

    /**
     * 检查执行人
     * @param executor
     */
    public void checkExecutor(String executor) {
        //从UserInfo中查询用户数据
        UserInfo userInfo = userInfoDao.getUserInfoByAccount(executor);
        if(null == userInfo){
            //从userDepRelate中查询到相关数据
            userInfo = userInfoDao.getUserInfoByAccountWithMd5(executor);
            if(null != userInfo){
                userInfoDao.add(userInfo);
            }else{
                userInfo = new UserInfo();
                UserDepAreaRelate userDepAreaRelate = userInfoDao.getUserDepAreaRelateByAccount(executor);
                if(null != userDepAreaRelate){
                    userInfo.setMd5(userDepAreaRelate.getMd5Passwd());
                }else{
                    userInfo.setMd5("-");
                }
                userInfo.setAccount(executor);
                userInfo.setPasswd("-");
                userInfoDao.add(userInfo);
            }

        }
    }

    /**
     * 自动更新用户密码 暂未启用
     */
    public void autoChangePwd() {
        try {
            //查询需要修改密码的用户
            List<UserInfo> userInfoList = userInfoDao.listUserForChangePwd();
            if(null != userInfoList && !userInfoList.isEmpty() ){
                for (UserInfo userInfo:userInfoList) {
                    //账号
                    String account = userInfo.getAccount();
                    //密码
                    String passwd = userInfo.getPasswd();
                    if(passwd.equals("111111")){
                        continue;
                    }

                    //查询密码的次数，判定管是否需要限定时间再次登录
                    int errorCount = accountLimitService.countAccountLimit(account);
                    if(errorCount > 5 ){
                        systemLogService.addSystemLog(account,"-","-1","密码错误超过五次！");
                    }

                    //获取认证信息
                    String token = TokenUtil.getTokenByAccount(account);
                    if(null == token ){
                        token = TokenUtil.initToken(account,passwd, Constant.MODEL_OAUTHUI);
                    }
                    //认证的cookie
                    String actCookie = TokenUtil.getCookie(token, Constant.MODEL_OAUTHUI);
                    //开始更新密码
                    WestarResult westarResult = ChangePwdUtil.autoChangePwd(actCookie, passwd);
                    systemLogService.addSystemLog(account,"-",westarResult.getStatus().toString(),westarResult.getMsg());

                    //登录成功，删除所有的密码错误记录
                    accountLimitService.deleteAccountLimit(account);
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
            logger.error("自动更新用户密码,操作异常!" + e.getMessage());
            systemLogService.addSystemLog("-","-","-3","自动更新用户密码,操作异常！");
        } catch (SelfHttpException e) {
            if(e.getCode().equals(SelfHttpException.PAGE_RE_LOGIN ) ){
                autoChangePwd();
            }else{
                systemLogService.addSystemLog("-","-","-3","自动更新用户密码,异常！"+e.getMsg());
            }
        }
    }
}
